package com.microsoft.tag.api.gateway.config;

import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.Set;

/**
 * 软件著作权:王艳明
 * 系统名称:SpringBoot后台管理系统
 *
 * @author WangYanming
 * @ClassName 类:SentinelGatewayConfig.java
 * @Description 功能描述:配置sentinel网关规则
 * @Version 1.0
 * @date 2025-10-16 下午 05:17
 */
@Configuration
public class SentinelGatewayConfig {

    /**
     * 初始化网关限流规则
     */
    @PostConstruct
    public void initGatewayRules() {
        // 定义API分组
        initApiDefinitions();

        // 配置网关流控规则
        Set<GatewayFlowRule> rules = new HashSet<>();

        // 1. 针对路由ID的限流规则
        rules.add(new GatewayFlowRule("user-service-route")
                .setCount(10)          // 限流阈值
                .setIntervalSec(1)     // 统计时间窗口，单位秒
                .setGrade(RuleConstant.FLOW_GRADE_QPS)  // 基于QPS限流
                .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT) // 直接拒绝
        );

        // 2. 针对API分组的限流规则
        rules.add(new GatewayFlowRule("user-api-group")
                .setCount(20)
                .setIntervalSec(1)
                .setGrade(RuleConstant.FLOW_GRADE_QPS)
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
        );

        // 3. 针对商品服务的限流规则
        rules.add(new GatewayFlowRule("product-service-route")
                .setCount(15)
                .setIntervalSec(1)
                .setGrade(RuleConstant.FLOW_GRADE_QPS)
        );

        // 加载规则
        GatewayRuleManager.loadRules(rules);
    }

    /**
     * 定义API分组
     */
    private void initApiDefinitions() {
        Set<ApiDefinition> definitions = new HashSet<>();

        // 用户服务API分组
        ApiDefinition userApi = new ApiDefinition("user-api-group")
                .setPredicateItems(new HashSet<ApiPathPredicateItem>() {{
                    add(new ApiPathPredicateItem().setPattern("/api/users/**")
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                    add(new ApiPathPredicateItem().setPattern("/api/profile/**")
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});

        // 商品服务API分组
        ApiDefinition productApi = new ApiDefinition("product-api-group")
                .setPredicateItems(new HashSet<ApiPathPredicateItem>() {{
                    add(new ApiPathPredicateItem().setPattern("/api/products/**")
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});

        definitions.add(userApi);
        definitions.add(productApi);

        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }
}
